package com.wanggsx.pluginlib;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import dalvik.system.DexClassLoader;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class PluginManager {

    private static final PluginManager mInstance = new PluginManager();

    private Context mContext;
    private PluginApk mPluginApk;

    public static PluginManager getInstance(){ return mInstance;}
    /** 初始化 */
    public void init(Context context){
        this.mContext = context.getApplicationContext();
    }
    /** 加载插件apk */
    public void loadApk(String apkPath) throws PackageManager.NameNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        //根据apk获取apk的包相关资源信息
        PackageInfo packageInfo = mContext.getPackageManager()
                .getPackageArchiveInfo(apkPath,
                        PackageManager.GET_ACTIVITIES|
                                PackageManager.GET_SERVICES);
        //如果没有获取到，则表示加载失败！
        if (packageInfo == null){
            return;
        }
        //创建DexClassLoader类加载器
        DexClassLoader classLoader =
                createDexClassLoader(apkPath);
        //创建AssetManager管理器
        AssetManager am = createAssertManager(apkPath);
        //根据AssetManager管理器，创建Resources资源管理器
        Resources resouces = createResource(am);
        //将相关d管理器和加载器封装到PluginApk对象中
        mPluginApk = new PluginApk(classLoader,am,resouces);
    }

    private Resources createResource(AssetManager am) {
        Resources resources = mContext.getResources();
        return new Resources(am,resources.getDisplayMetrics(),resources.getConfiguration());
    }

    private AssetManager createAssertManager(String apkPath) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        AssetManager assetManager = AssetManager.class.newInstance();
        Method method = AssetManager.class.getDeclaredMethod("addAssetPath",String.class);
        method.invoke(assetManager,apkPath);
        return assetManager;
    }

    private DexClassLoader createDexClassLoader(String apkPath) {
        File file = mContext.getDir("dex",Context.MODE_PRIVATE);
        return new DexClassLoader(apkPath,file.getAbsolutePath(),null,mContext.getClassLoader());
    }

    public PluginApk getmPluginApk() {
        return mPluginApk;
    }
}
